package com.campus.app.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.campus.app.mapper.*;
import com.campus.app.service.GoodClassService;
import com.campus.commons.entity.*;
import com.campus.commons.utils.Result;
import com.campus.commons.utils.Tool;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.*;

@Repository
/**
 * 文明班级评选实现类
 */
public class GoodClassServiceImpl<T> extends ServiceImpl<GoodClassMapper, GoodClass> implements GoodClassService {
    /**
     * 开始时间
     */
    private String beginTime;
    /**
     * 结束
     */
    private String endTime;
    /**
     * 是否被标记
     */
    private int isRed;
    /**
     * 出勤
     */
    private int work;



  private   List<Integer> goodClass = new ArrayList<>();
    @Autowired
    private CheckEveningMapper checkEveningMapper;
    @Autowired
    private CheckMorningExerciseMapper checkMorningExerciseMapper;
    @Autowired
    private CheckHealthMapper checkHealthMapper;
    @Autowired
    private CheckClassMapper checkClass;
    @Autowired
    private GoodClassMapper goodClassMapper;
    @Autowired
    private CheckDormMapper checkDormMapper;


    /**
     * 计算文明班级主方法
     *
     * @param idRed
     * @param work
     * @param beginTime
     * @param endTime
     *
     * @return
     */
    @Override
    public Result<List<GoodClass>> GoodClass(int idRed, int work, String beginTime, String endTime, int page, int limit) {
        Result<List<GoodClass>> result = new Result<>();
        setWork(work);
        setIsRed(idRed);
        setBeginTime(beginTime);
        setEndTime(endTime);

        try {
            /**
             * 整体是个方法循环过滤 ,如果又有新的过滤需求，就实现接口或写内部方法
             * checkEvening方法即是循环开始又是循环结束（循环方法共1次） ，如果过滤不要checkEvening
             * 就设定其他方法为循环的开始和结束，若有新增过滤就直接在循环中任意位置调用你的方法
             * 这里中间如果出现异常，就是 集合中没有符合条件的参数，直接手动抛出
             */
            checkEvening();
            check_morning_exercise();
            check_health();
            checkClass();
            checkDorm();
            checkEvening();
        } catch (Exception e) {
            result.setCode(0);
            result.setTotal(0);
            result.setData(null);
            result.setMsg("没有查询结果");
            return result;
        }


        HashSet<Integer> set = new HashSet(goodClass);
        Result<List<GoodClass>> calculate = Calculate(page, limit, set.toArray());
        return calculate;
    }

    @Override
    public Result<List<GoodClass>> monthlyAndWeekStatistics(int page, int limit, String beginTime, String endTime) {
   if (StringUtils.isEmpty(beginTime)){
       beginTime = Tool._7DaysBefore(new Date());
   }
   if (StringUtils.isEmpty(endTime)){
       endTime = Tool.getDateToString(new Date());
   }
        setBeginTime(beginTime);
        setEndTime(endTime);
        Result<List<GoodClass>> calculate = Calculate(page, limit, null);
        return calculate;
    }

    /**
     * 计算主体
     *
     * @param page
     * @param limit
     * @param list
     * @return
     */
    public Result<List<GoodClass>> Calculate(int page, int limit, Object[] list) {
        QueryWrapper<GoodClass> queryWrapper = new QueryWrapper<>();
        queryWrapper.between("checkClassDate", beginTime, endTime);
        queryWrapper.between("checkEveningDate", beginTime, endTime);
        queryWrapper.between("checkHealthDate", beginTime, endTime);
        queryWrapper.between("checkMorningDate", beginTime, endTime);
        queryWrapper.between("checkDormDate", beginTime, endTime);
        queryWrapper.select(" teacherId", " AVG(checkClassWork) as checkClassWork, " +
                "sum(checkEveningIsRed) as checkEveningIsRed " +
                ",sum(checkHealthIsRed) as checkHealthIsRed " +
                ",AVG(checkMorningWork) as checkMorningWork " +
                ",AVG(formalWork) as formalWork " +
                ",AVG(checkHealthScore) as checkHealthScore " +
                ",AVG(checkDormScore)  as checkDormScore " +
                ",className" +
                ",id");
        queryWrapper.groupBy("className");
        if (list!=null) {
            queryWrapper.in("id", list);
        }
        Page<GoodClass> goodClassPage = goodClassMapper.selectPage(new Page<GoodClass>(page, limit), queryWrapper);
        return Result.result(goodClassPage);
    }

    int enter = 0;

    /**
     * 筛选没被标红的晚自习班级
     */
    public void checkEvening() {
        QueryWrapper<CheckEvening> queryWrapper = new QueryWrapper<>();
        if (enter != 1) {
            enter += 1;
        } else {
            queryWrapper.in("classId", goodClass);
            enter = 0;
        }

        queryWrapper.between("date", beginTime, endTime);
        queryWrapper.eq("isRed", isRed);
        queryWrapper.select("classId");
        queryWrapper.groupBy("classId");
        List<CheckEvening> checkEvenings = checkEveningMapper.selectList(queryWrapper);
        goodClassClear();
        for (CheckEvening evening : checkEvenings) {
            goodClassAdd(evening.getClassid());
        }
    }

    /**
     * 筛选晨练出勤合格的班级
     */
    public void check_morning_exercise() {
        QueryWrapper<CheckMorningExercise> queryWrapper = new QueryWrapper<>();
        queryWrapper.ge("work", work);
        QueryWrapper<CheckMorningExercise> tQueryWrapper = addGueryWrapper((QueryWrapper<T>) queryWrapper);
        List<CheckMorningExercise> exercises = checkMorningExerciseMapper.selectList(tQueryWrapper);
        goodClassClear();
        for (CheckMorningExercise exercise : exercises) {
            goodClassAdd(exercise.getClassid());
        }

    }

    /**
     * 筛选卫生合格的班级
     */
    public void check_health() {
        QueryWrapper<CheckHealth> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("isRed", isRed);
        QueryWrapper<CheckHealth> tQueryWrapper = addGueryWrapper((QueryWrapper<T>) queryWrapper);
        List<CheckHealth> checkHealths = checkHealthMapper.selectList(tQueryWrapper);
        goodClassClear();
        for (CheckHealth health : checkHealths) {
            goodClass.add(health.getClassid());
        }
    }

    /**
     * 筛选查班出勤合格的班级
     */
    public void checkClass() {
        QueryWrapper<CheckClass> queryWrapper = new QueryWrapper<>();
        queryWrapper.ge("work", work);
        QueryWrapper<CheckClass> tQueryWrapper = addGueryWrapper((QueryWrapper<T>) queryWrapper);
        List<CheckClass> checkClasses = checkClass.selectList(tQueryWrapper);
        goodClassClear();
        for (CheckClass aClass : checkClasses) {
            goodClassAdd(aClass.getClassid());
        }
    }

    /**
     * 筛选出合格的宿舍
     */
    public void checkDorm() {
        QueryWrapper<CheckDorm> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("isRed", isRed);
        queryWrapper.between("dateTime", beginTime, endTime);
        queryWrapper.select("classId");
        queryWrapper.groupBy("classId");
        queryWrapper.in("classId", goodClass);
        List<CheckDorm> checkDorms = checkDormMapper.selectList(queryWrapper);
        goodClassClear();
        for (CheckDorm checkDorm : checkDorms) {
            goodClassAdd(checkDorm.getClassId());
        }

    }

    /**
     * 去重操作方法
     *
     * @param tQueryWrapper
     * @return
     */
    public QueryWrapper addGueryWrapper(QueryWrapper<T> tQueryWrapper) {
        tQueryWrapper.between("date", beginTime, endTime);
        tQueryWrapper.select("classId");
        tQueryWrapper.groupBy("classId");
        tQueryWrapper.in("classId", goodClass);
        return tQueryWrapper;
    }

    /**
     * 清除现存班级
     */
    public void goodClassClear() {
        goodClass.clear();


    }

    /**
     * 添加现存班级
     *
     * @param add
     */
    public void goodClassAdd(Integer add) {
        goodClass.add(add);
    }


    public String getBeginTime() {
        return beginTime;
    }

    public void setBeginTime(String beginTime) {
        this.beginTime = beginTime;
    }

    public String getEndTime() {
        return endTime;
    }

    public void setEndTime(String endTime) {
        this.endTime = endTime;
    }

    public int getIsRed() {
        return isRed;
    }

    public void setIsRed(int isRed) {
        this.isRed = isRed;
    }

    public int getWork() {
        return work;
    }

    public void setWork(int work) {
        this.work = work;
    }
}
